package ru.spbau.design.snmp.android.viewer.view;

import java.util.HashMap;
import java.util.Map;

import ru.spbau.design.snmp.android.viewer.R;
import ru.spbau.design.snmp.android.viewer.model.NetInterface;
import ru.spbau.design.snmp.android.viewer.model.NetNode;
import ru.spbau.design.snmp.android.viewer.model.SubNet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import android.widget.TextView;

class SubnetsTab implements Listener {
	ExpandableListView view;
	SubnetAdapter adapter;
	SubnetsViewClickListener listener;
	ViewerActivity.Accessor accessor;

	public SubnetsTab(ViewerActivity.Accessor accessor) {
		this.accessor = accessor;

		this.view = (ExpandableListView) this.accessor.context().findViewById(
				R.id.subnetsView);
		this.listener = new SubnetsViewClickListener();
		this.adapter = new SubnetAdapter();

		this.view.setAdapter(this.adapter);
		this.view.setOnChildClickListener(this.listener);
		
		accessor.viewerActivity.subscribe(this.adapter);
	}
	
	public ExpandableListView getView() {
		return view;
	}
	
	public Rev getSubnetPos(NetNode node) {
		return this.adapter.getPos(node);
	}
	
	public void onConfigurationChanged() {
		this.view.invalidateViews();
	}
	
	// --------------------------------------------------------------------------------

	private class SubnetAdapter extends AdapterBase implements Listener {
		Map<NetNode, Rev> rev;
		int maxChildren;

		public SubnetAdapter() {
			this.rev = new HashMap<NetNode, Rev>();
		}

		public Rev getPos(NetNode node) {
			Rev res = this.rev.get(node);
			
			if (res == null) {
				System.out.println("Position for node " + node.getAddress().getAddressStr() + " not found. Available positions:");
				for (Map.Entry<NetNode, Rev> e : rev.entrySet()) {
					System.out.println(e.getKey().getAddress().getAddressStr() + " " + String.valueOf(e.getValue().getGroup()) + " " + String.valueOf(e.getValue().getChild()));
				}
			}
			
			return res;
		}

		public int getPos(SubNet subnet) {
			return this.rev.get(subnet.getNodes().get(0)).getGroup();
		}

		public View getChildView(int groupPosition, int childPosition,
				boolean isExpanded, View convertView, ViewGroup viewGroup) {

			TextView tv = (TextView) convertView;
			if (tv == null) {
				tv = new TextView(accessor.context());
			}
			
			NetNode node = accessor.network().getSubNets().get(groupPosition).getNodes().get(childPosition);
			if (node.getName().length() == 0) {
				tv.setText(node.getAddress().getAddressStr());
			} else {
				tv.setText(node.getAddress().getAddressStr() + " (" + node.getName() + ")");
			}
			return tv;
		}

		public NetNode getChild(int groupPos, int childPos) {
			if (accessor.network() == null) {
				return null;
			}
			
			return accessor.network().getSubNets().get(groupPos).getNodes().get(
					childPos);
		}

		public int getChildrenCount(int groupPosition) {
			if (accessor.network() == null) {
				return 0;
			}
			
			return accessor.network().getSubNets().get(groupPosition).getNodes()
					.size();
		}

		public long getCombinedChildId(long groupId, long childId) {
			return groupId * this.maxChildren + (childId + 1);
		}

		public long getCombinedGroupId(long groupId) {
			return groupId * this.maxChildren;
		}

		public int getGroupCount() {
			if (accessor.network() == null) {
				return 0;
			}
			
			return accessor.network().getSubNets().size();
		}

		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {

			TextView tv = (TextView) convertView;
			if (tv == null) {
				tv = new TextView(accessor.context());
			}

			tv.setText(accessor.network().getSubNets().get(groupPosition).getId());
			tv.setMinHeight(50);
			tv.setGravity(android.view.Gravity.CENTER_VERTICAL);
			return tv;
		}

		public boolean isEmpty() {
			if (accessor.network() == null) {
				return true;
			}
			
			return accessor.network().getRouters().isEmpty();
		}

		public void onConfigurationChanged() {
			int nSubnet = 0;
			this.maxChildren = 0;
			this.rev.clear();
			while (nSubnet < accessor.network().getSubNets().size()) {
				SubNet subnet = accessor.network().getSubNets().get(nSubnet);

				int nNode = 0;
				while (nNode < subnet.getNodes().size()) {
					NetNode node = subnet.getNodes().get(nNode);
					this.rev.put(node, new Rev(nSubnet, nNode));
					nNode++;
					
					if (this.maxChildren < subnet.getNodes().size()) {
						this.maxChildren = subnet.getNodes().size();
					}
				}

				nSubnet++;
			}
			
			this.maxChildren++;
		}
	}

	private class SubnetsViewClickListener implements
			ExpandableListView.OnChildClickListener {

		public SubnetsViewClickListener() { }

		public boolean onChildClick(ExpandableListView parent, View v,
				int groupPos, int childPos, long id) {

			NetNode node = adapter.getChild(groupPos, childPos);
			SubNet subnet = node.getSubNet();

			for (NetInterface ni : subnet.getRouterInterfaces()) {
				if (ni.getAddress().equals(node.getAddress())) {
					Rev vPos = accessor.getRouterPos(ni);

					accessor.tabs().setCurrentTabByTag("Routers");
					accessor.routersView().expandGroup(vPos.getGroup());
					accessor.routersView().setSelectedChild(vPos
							.getGroup(), vPos.getChild(), true);
					//this.viewerActivity.routersView.setSelected(true);
				}
			}

			return true;
		}
	}
}
